#include <iostream>
#include <assert.h>
using namespace std;

namespace csd
{
    template <class T>
    struct list_node
    {
        T data;
        list_node<T>* _prev;
        list_node<T>* _next;

        list_node(const T& val = T())
            :data(val)
            ,_prev(nullptr)
            ,_next(nullptr)
            {  }

    };

    template <class T ,class Ref,class Ptr>
    struct __list_iterator
    {
       typedef list_node<T> Node;
       typedef __list_iterator<T,Ref,Ptr> self;
       Node* _node;

       __list_iterator(Node* node)
           :_node(node)
       {  }
        
        bool operator!= (const self& it)const 
        {
            return _node != it._node;
        }

        bool operator==(const self& it)const 
        {
            return _node == it._node;
        }

        Ref operator* ()
        {
            return _node->data;
        }

        Ptr operator->()
        {
            return &(operator*());
        }

        self& operator++()
        {
            _node = _node->_next;
            return *this;
        }
        
        self operator++(int)
        {
            self tmp(*this);
            _node = _node->_next;
            return tmp;
        }

        self& operator--()
        {
            _node = _node->_prev;
            return *this;
        }

        self operator--(int)
        {
            self tmp(*this);
            _node = _node->_prev;
            return tmp;
        }
    };

    template <class T>
    class list 
    {
        typedef list_node<T> Node;
    public:
        typedef __list_iterator<T,T&,T*> iterator;
        typedef __list_iterator<T,const T&,const T*> const_iterator;
        

        iterator begin()
        {
            return iterator(_head->_next);
        }

        iterator end()
        {
            return iterator(_head);
        }

        const_iterator begin()const 
        {
            return const_iterator(_head->_next);
        }

        const_iterator end()const 
        {
            return const_iterator(_head);
        }
        
        list()
        {
            _head = new Node;
            _head->_prev = _head;
            _head->_next = _head;
        }

       //拷贝构造 
        list(const list<T>& lt)
        {
            _head = new Node;
            _head->_prev = _head;
            _head->_next = _head;

            for(const auto& e : lt)
            {
                push_back(e);
            }
        }

        //赋值重载
        list<T>& operator=( list<T> lt)
        {
            swap(lt);
            return *this;
        }
        
        void swap(list<T>& lt)
        {
            std::swap(_head,lt._head);//交换两个list的哨兵头结点指针即可
        }

      //  list<T>& operator=(const list<T>& lt)
      //  {
      //      if(*this != lt)
      //      {
      //          clear();
      //          for(const auto& e : lt)
      //          {
      //              push_back(e);
      //          }
      //      }
      //      return *this;
      //  }
        
    
        ~list()
        {
            clear();//清理容器
            delete _head;
            _head = nullptr;
        }
        
        void clear()
        {
            iterator it = begin();
            while(it != end())//遍历删除每个节点
            {
                it = erase(it);//每次删除后接受下一个位置的迭代器
            }
        }

        bool empty()
        {
            return begin() == end();//当list中只有哨兵头结点时，list为空
        }

        size_t size()const 
        {
            size_t sz = 0;//统计有效数据个数
            const_iterator it = begin();//第一个有效数据的迭代器
            while(it != end())
            {
                sz++;
                it++;
            }

            return sz;
        }

        void resize(size_t n,const T& val = T())
        {
            size_t len = 0;
            iterator it = begin();
            while(len < n && it != end())
            {
                len++;
                it++;
            }

            if(len == n)//说明容器中的有效数据个数是大于或等于n
            {
                while(it != end())//只保存前n个有效数据
                {
                    it = erase(it);
                }
            }
            else//说明有效数据个数小于n 
            {
                while(len < n)//尾插数据为val的结点，直到容器当中的有效数据个数为n
                {
                    push_back(val);
                    len++;
                }
            }
        }


        void push_back(const T& x)
        {
            Node* tail = _head->_prev;
            Node* newnode = new Node(x);
            tail->_next = newnode;
            newnode->_prev = tail;
            newnode->_next = _head;
            _head->_prev = newnode;
        }
        
        iterator insert(iterator pos,const T& x)
        {
            Node* cur = pos._node;
            Node* prev = cur->_prev;
            Node* newnode = new Node(x);
            //prev newnode cur 
            prev->_next = newnode;
            newnode->_prev = prev;
            newnode->_next = cur;
            cur->_prev = newnode;

            return iterator(newnode);
        }

        void push_front(const T& x)
        {
            insert(begin(),x);
        }
        
        iterator erase(iterator pos)
        {
            assert(pos._node);//检查pos的合法性
            assert(pos != end());//不能删除哨兵头结点
            Node* cur = pos._node;//迭代器pos位置的节点指针
            Node* prev = cur->_prev;
            Node* next = cur->_next;
            //prev cur next 
            delete cur;//释放pos位置节点
            prev->_next = next;
            next->_prev = prev;

            return iterator(next);//返回删除位置的下一个位置的迭代器
        }
        
        void pop_back()
        {
            erase(--end());
        }

        void pop_front()
        {
            erase(begin());
        }


    private:
        Node* _head;
    };

    void test_list1()
    {
        list<int> lt;
        lt.push_back(1);
        lt.push_back(2);
        lt.push_back(3);
        lt.push_back(4);
        lt.push_back(5);
        
        cout << lt.size() << " ";
        lt.resize(10,8);

        list<int>::iterator it = lt.begin();
        while(it != lt.end())
        {
            cout << *it << " ";
            it++;
        }
    }
}

int main()
{
    csd::test_list1();
    return 0;
}


